package com.yanzhen.utils;

import com.mysql.cj.jdbc.MysqlDataSource;
import org.apache.mahout.cf.taste.common.TasteException;
import org.apache.mahout.cf.taste.impl.common.LongPrimitiveIterator;
import org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel;
import org.apache.mahout.cf.taste.impl.neighborhood.NearestNUserNeighborhood;
import org.apache.mahout.cf.taste.impl.recommender.GenericUserBasedRecommender;
import org.apache.mahout.cf.taste.impl.similarity.EuclideanDistanceSimilarity;
import org.apache.mahout.cf.taste.model.DataModel;
import org.apache.mahout.cf.taste.model.JDBCDataModel;
import org.apache.mahout.cf.taste.neighborhood.UserNeighborhood;
import org.apache.mahout.cf.taste.recommender.RecommendedItem;
import org.apache.mahout.cf.taste.recommender.Recommender;
import org.apache.mahout.cf.taste.similarity.UserSimilarity;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Hello world!
 *
 */
public class MahoutUtils
{
    final static int NEIGHBORHOOD_NUM = 2;
    final static int RECOMMENDER_NUM = 3;

    public static List<Long> getRecommendPost(Integer userId) throws IOException, TasteException {

        MysqlDataSource dataSource = new MysqlDataSource();
        dataSource.setServerName("localhost");
        dataSource.setUser("root");
        dataSource.setUrl("jdbc:mysql://localhost:3306/job?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false");
        dataSource.setPassword("123456");
        dataSource.setDatabaseName("job");
        //创建基于数据库的数据模型
        JDBCDataModel dataModel = new MySQLJDBCDataModel(dataSource, "tb_mahout", "uid", "iid", "val", "time");
        //System.out.println(dataModel.exportWithIDsOnly());
        DataModel model = dataModel;
        //基于皮尔森相关性的相似度 —— Pearson correlation-based similarity
        //https://blog.csdn.net/ifnoelse/article/details/7765984
        //https://blog.csdn.net/weixin_42229056/article/details/82970923
        //计算相似度，相似度算法有很多种，欧几里得、皮尔逊等等。
        //UserSimilarity similarity=new PearsonCorrelationSimilarity(model);
        UserSimilarity similarity=new EuclideanDistanceSimilarity(model);
        //计算最近邻域，邻居有两种算法，基于固定数量的邻居和基于相似度的邻居，这里使用基于固定数量的邻居
        UserNeighborhood neighborhood=new NearestNUserNeighborhood(2,similarity,model);
        //构建推荐器:协同过滤推荐有两种，分别是基于用户的和基于物品的，这里使用基于用户的协同过滤推荐
        Recommender r=new GenericUserBasedRecommender(model,neighborhood,similarity);

        /*//给用户ID等于1的用户推荐3条数据
        List<RecommendedItem> recommendations = recommender.recommend(1 ,3);
        System.out.println(recommendations.size());
        for (RecommendedItem recommendation : recommendations) {
            System.out.println(recommendation);
            System.out.println(recommendation.getItemID());
            System.out.println(recommendation.getValue());
        }

        String file = "d:\\1.csv";
        DataModel model2 = new FileDataModel(new File(file));
        UserSimilarity user = new EuclideanDistanceSimilarity(model2);
        NearestNUserNeighborhood neighbor = new NearestNUserNeighborhood(NEIGHBORHOOD_NUM, user, model);
        Recommender r = new GenericUserBasedRecommender(model, neighbor, user);*/
        LongPrimitiveIterator iter = model.getUserIDs();
        List<Long> postIdList = new ArrayList<>();
        while (iter.hasNext()) {
            long uid = iter.nextLong();
            List<RecommendedItem> list = r.recommend(uid, RECOMMENDER_NUM);
            for (RecommendedItem ritem : list) {
                //System.out.printf("(%s,%f)", ritem.getItemID(), ritem.getValue());
                System.out.print(uid);
                System.out.print(ritem.getItemID());
                System.out.print(ritem.getValue());
                System.out.println("=====");
                /*if(uid == userId.intValue()){

                }*/
                postIdList.add(ritem.getItemID());
            }
        }
        return postIdList;
    }
}
